package com.jeequan.jeepay.service.impl;

//package .service.impl;

import cn.hutool.core.util.StrUtil;
import com.jeequan.jeepay.core.constants.BalanceOperateTypeEnum;
import com.jeequan.jeepay.core.constants.StateEnum;
import com.jeequan.jeepay.core.entity.Balance;
import com.jeequan.jeepay.core.utils.CommonUtil;
import com.jeequan.jeepay.core.utils.LogUtils;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.service.BalanceLogService;
import com.jeequan.jeepay.service.BalanceService;
import com.jeequan.jeepay.service.mapper.BalanceMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;

import java.math.BigDecimal;
//import .entity.Balance;
//import .mapper.BalanceMapper;
//import .service.BalanceService;

/**
 * 钱包;(balance)表服务实现类
 *
 * @author : wondream322@gmail.com
 * @date : 2023-8-19
 */
@Service
public class BalanceServiceImpl implements BalanceService {
    @Autowired
    private BalanceMapper balanceMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    public Balance queryById(Integer id) {
        return balanceMapper.selectById(id);
    }

    /**
     * 分页查询
     *
     * @param balance 筛选条件
     * @param current 当前页码
     * @param size    每页大小
     * @return
     */
    public Page<Balance> paginQuery(Balance balance, long current, long size) {
        //1. 构建动态查询条件
        LambdaQueryWrapper<Balance> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(balance.getRemark())) {
            queryWrapper.eq(Balance::getRemark, balance.getRemark());
        }
        //2. 执行分页查询
        Page<Balance> pagin = new Page<>(current, size, true);
        IPage<Balance> selectResult = balanceMapper.selectByPage(pagin, queryWrapper);
        pagin.setPages(selectResult.getPages());
        pagin.setTotal(selectResult.getTotal());
        pagin.setRecords(selectResult.getRecords());
        //3. 返回结果
        return pagin;
    }

    /**
     * 新增数据
     *
     * @param balance 实例对象
     * @return 实例对象
     */
    public Balance insert(Balance balance) {
        balanceMapper.insert(balance);
        return balance;
    }

    /**
     * 更新数据
     *
     * @param balance 实例对象
     * @return 实例对象
     */
    public Balance update(Balance balance) {
        //1. 根据条件动态更新
        LambdaUpdateChainWrapper<Balance> chainWrapper = new LambdaUpdateChainWrapper<Balance>(balanceMapper);
        if (StrUtil.isNotBlank(balance.getRemark())) {
            chainWrapper.set(Balance::getRemark, balance.getRemark());
        }
        //2. 设置主键，并更新
        chainWrapper.eq(Balance::getId, balance.getId());
        boolean ret = chainWrapper.update();
        //3. 更新成功了，查询最最对象返回
        if (ret) {
            return queryById(balance.getId());
        } else {
            return balance;
        }
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    public boolean deleteById(Integer id) {
        int total = balanceMapper.deleteById(id);
        return total > 0;
    }

    /**
     * 增加余额
     */
    @Override
    public boolean addBalance(Integer memberId, Integer balanceType, Integer balanceLevel, BigDecimal balance, Integer sourceType, Integer sourceId) {
        // 1.检查钱包
        Balance balanceDO = createIfNotExists(memberId, balanceType, balanceLevel);
        // 2.增加余额
        BigDecimal oldBalance = balanceDO.getBalance();
        BigDecimal newBalance = oldBalance.add(balance);
        BigDecimal oldTotalBalance = balanceDO.getTotalBalance();
        BigDecimal newTotalBalance = oldTotalBalance.add(balance);
        balanceDO.setBalance(newBalance);
        balanceDO.setTotalBalance(newTotalBalance);
        this.update(balanceDO);
        // 3.增加流水日志
        try {
            BalanceLogService balanceLogService = SpringBeansUtil.getBean(BalanceLogService.class);
            balanceLogService.addBalanceLog(memberId, balanceType, balanceLevel, balance, oldBalance, newBalance, sourceType, sourceId, BalanceOperateTypeEnum.ADD.getType());
        } catch (Exception e) {
            LogUtils.op("BalanceServiceImpl.addBalance").msg("3.增加流水日志").kv("异常信息", e.getMessage()).info();
        }
        return true;
    }

    /**
     * 减少余额
     */
    @Override
    public boolean deductBalance(Integer memberId, Integer balanceType, Integer balanceLevel, BigDecimal balance, Integer sourceType, Integer sourceId) {
        // 1.检查钱包
        Balance balanceDO = createIfNotExists(memberId, balanceType, balanceLevel);
        // 2.扣除余额
        if (balanceDO.getBalance().compareTo(balance)<0) {
            return false;
        }
        BigDecimal oldBalance = balanceDO.getBalance();
        BigDecimal newBalance = oldBalance.subtract(balance);
        BigDecimal oldTotalBalance = balanceDO.getTotalBalance();
        BigDecimal newTotalBalance = oldTotalBalance.subtract(balance);
        balanceDO.setBalance(newBalance);
        balanceDO.setTotalBalance(newTotalBalance);
        this.update(balanceDO);
        // 3.增加流水日志
        try {
            BalanceLogService balanceLogService = SpringBeansUtil.getBean(BalanceLogService.class);
            balanceLogService.addBalanceLog(memberId, balanceType, balanceLevel, balance, oldBalance, newTotalBalance, sourceType, sourceId, BalanceOperateTypeEnum.DEDUCT.getType());
        } catch (Exception e) {
            LogUtils.op("BalanceServiceImpl.addBalance").msg("3.增加流水日志").kv("异常信息", e.getMessage()).info();
        }
        return true;
    }

    /**
     * 检查钱包，如果不存在则创建
     */
    @Override
    public Balance createIfNotExists(Integer memberId, Integer balanceType, Integer balanceLevel) {
//         Map<String, Object> columnMap = new HashMap<>(4);
//         columnMap.put("memberId", memberId);
//         columnMap.put("balanceType", balanceType);
//         columnMap.put("balanceLevel", balanceLevel);
//         columnMap.put("state", 1);
//         List<Balance> balances = balanceMapper.selectByMap(columnMap);
        LambdaQueryWrapper<Balance> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Balance::getMemberId, memberId);
        queryWrapper.eq(Balance::getBalanceType, balanceType);
        queryWrapper.eq(Balance::getBalanceLevel, balanceLevel);
        queryWrapper.eq(Balance::getState, StateEnum.VALID.getState());
        Balance balance = balanceMapper.selectOne(queryWrapper);
        if (CommonUtil.isNotEmpty(balance)) {
            return balance;
        }
        balance = new Balance();
        balance.setMemberId(memberId);
        balance.setBalanceType(balanceType);
        balance.setBalanceLevel(balanceLevel);
        this.insert(balance);
        return balance;
    }

}